//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_IO_H__
#define __ELASTOS_IO_H__

typedef uint16_t    ioport_t;

#define InbDelay(port)          Inb(port)
#define InwDelay(port)          Inw(port)
#define InlDelay(port)          Inl(port)

#define OutbDelay(port, data)   Outb(port, data)
#define OutwDelay(port, data)   Outw(port, data)
#define OutlDelay(port, data)   Outl(port, data)

INLINE uint8_t Inb(ioport_t port)
{
    uint8_t u8Data;
    ASM("inb    %%dx, %%al;"
        :"=a"(u8Data) :"d"(port));
    return u8Data;
}

INLINE uint16_t Inw(ioport_t port)
{
    uint16_t u16Data;
    ASM("inw    %%dx, %%ax;"
        :"=a"(u16Data) :"d"(port));
    return u16Data;
}

INLINE uint32_t Inl(ioport_t port)
{
    uint32_t u32Data;
    ASM("inl    %%dx, %%eax;"
        :"=a"(u32Data) :"d"(port));
    return u32Data;
}

INLINE void Insb(ioport_t port, void *buffer, size_t size)
{
    ASM("mov    %%eax, %%edi;"
        "rep insb;"
        : :"d"(port), "a"(buffer), "c"(size) :"edi");
}

INLINE void Insw(ioport_t port, void *buffer, size_t size)
{
    ASM("mov    %%eax, %%edi;"
        "rep insw;"
        : :"d"(port), "a"(buffer), "c"(size >> 1) :"edi");
}

INLINE void Insl(ioport_t port, void *buffer, size_t size)
{
    ASM("mov    %%eax, %%edi;"
        "rep insl;"
        : :"d"(port), "a"(buffer), "c"(size >> 2) :"edi");
}

INLINE void Outb(ioport_t port, uint8_t u8Data)
{
    ASM("outb   %%al, %%dx;"
        : :"a"(u8Data), "d"(port));
}

INLINE void Outw(ioport_t port, uint16_t u16Data)
{
    ASM("outw   %%ax, %%dx;"
        : :"a"(u16Data), "d"(port));
}

INLINE void Outl(ioport_t port, uint32_t u32Data)
{
    ASM("outl   %%eax, %%dx;"
        : :"a"(u32Data), "d"(port));
}

INLINE void Outsb(ioport_t port, const void *buffer, size_t size)
{
    ASM("mov    %%eax, %%esi;"
        "rep outsb;"
        : :"d"(port), "a"(buffer), "c"(size) :"esi");
}

INLINE void Outsw(ioport_t port, const void *buffer, size_t size)
{
    ASM("mov    %%eax, %%esi;"
        "rep outsw;"
        : :"d"(port), "a"(buffer), "c"(size >> 1) :"esi");
}

INLINE void Outsl(ioport_t port, const void *buffer, size_t size)
{
    ASM("mov    %%eax, %%esi;"
        "rep outsl;"
        : :"d"(port), "a"(buffer), "c"(size >> 2) :"esi");
}

#endif //__ELASTOS_IO_H__
